using System;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;

namespace OracleInternal.TTC
{
	internal class TTCProtocolNegotiation : TTCMessage
	{
		internal static short ORACLE8_PROD_VERSION = 8030;

		internal static short ORACLE81_PROD_VERSION = 8100;

		internal static short MIN_OVERSION_SUPPORTED = 7230;

		internal const byte MIN_TTCVER_SUPPORTED = 4;

		internal const byte V8_TTCVER_SUPPORTED = 5;

		internal const byte MAX_TTCVER_SUPPORTED = 6;

		private short m_serverCharSet;

		private short m_serverCharSetElem;

		private byte m_serverFlags;

		private short m_serverNCharSet;

		private byte[] m_protocolServerString;

		private byte m_protocolServerVersion;

		private short m_oVersion = -1;

		private static byte[] m_protocolClientVersion = new byte[2]
		{
			6,
			0
		};

		private static byte[] m_protocolClientString = new byte[16]
		{
			79,
			68,
			80,
			46,
			78,
			69,
			84,
			95,
			77,
			97,
			110,
			97,
			103,
			101,
			100,
			0
		};

		internal byte[] m_serverCompiletimeCapabilities;

		internal byte[] m_serverRuntimeCapabilities;

		internal short ServerCharacterSet => m_serverCharSet;

		internal short ServerNCharacterSet => m_serverNCharSet;

		internal byte ServerFlags => m_serverFlags;

		internal byte[] ServerCompileTimeCapabilities => m_serverCompiletimeCapabilities;

		internal byte[] ServerRunTimeCapabilities => m_serverRuntimeCapabilities;

		internal TTCProtocolNegotiation(MarshallingEngine marshallingEngine)
			: base(marshallingEngine, 1)
		{
		}

		internal override void ReInit(MarshallingEngine marshallingEngine)
		{
			base.ReInit(marshallingEngine);
			m_serverCharSet = 0;
			m_serverCharSetElem = 0;
			m_serverFlags = 0;
			m_serverNCharSet = 0;
			m_protocolServerString = null;
			m_protocolServerVersion = 0;
			m_oVersion = -1;
			m_serverCompiletimeCapabilities = null;
			m_serverRuntimeCapabilities = null;
		}

		internal void WriteMessage()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131328, OracleTraceClassName.TTCProtocolNegotiation, OracleTraceFuncName.WriteMessage);
			}
			try
			{
				WriteTTCCode();
				m_marshallingEngine.MarshalB1Array(m_protocolClientVersion);
				m_marshallingEngine.MarshalB1Array(m_protocolClientString);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268566528, OracleTraceClassName.TTCProtocolNegotiation, OracleTraceFuncName.WriteMessage, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131584, OracleTraceClassName.TTCProtocolNegotiation, OracleTraceFuncName.WriteMessage);
				}
			}
		}

		internal void ReadResponse()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131328, OracleTraceClassName.TTCProtocolNegotiation, OracleTraceFuncName.ReadResponse);
			}
			try
			{
				if ((byte)m_marshallingEngine.UnmarshalUB1() != 1)
				{
					throw new Exception("TTC Protocol Error");
				}
				m_protocolServerVersion = (byte)m_marshallingEngine.UnmarshalUB1();
				switch (m_protocolServerVersion)
				{
				case 4:
					m_oVersion = MIN_OVERSION_SUPPORTED;
					break;
				case 5:
					m_oVersion = ORACLE8_PROD_VERSION;
					break;
				case 6:
					m_oVersion = ORACLE81_PROD_VERSION;
					break;
				default:
					throw new Exception("TTC Protocol Error");
				}
				m_marshallingEngine.UnmarshalUB1();
				m_protocolServerString = m_marshallingEngine.UnmarshalTEXT(50);
				m_serverCharSet = (short)m_marshallingEngine.UnmarshalUB2();
				m_serverFlags = (byte)m_marshallingEngine.UnmarshalUB1();
				if ((m_serverCharSetElem = (short)m_marshallingEngine.UnmarshalUB2()) > 0)
				{
					m_marshallingEngine.UnmarshalNBytes(m_serverCharSetElem * 5);
				}
				byte[] representationArray = m_marshallingEngine.m_typeRepresentation.m_representationArray;
				byte b = representationArray[1];
				representationArray[1] = 0;
				int length = m_marshallingEngine.UnmarshalUB2();
				representationArray[1] = b;
				byte[] array = m_marshallingEngine.UnmarshalNBytes(length);
				int num = 6 + (array[5] & 0xFF) + (array[6] & 0xFF);
				m_serverNCharSet = (short)((array[num + 3] & 0xFF) << 8);
				m_serverNCharSet |= (short)(array[num + 4] & 0xFF);
				int num2 = m_marshallingEngine.UnmarshalUB1();
				m_serverCompiletimeCapabilities = new byte[num2];
				for (int i = 0; i < num2; i++)
				{
					m_serverCompiletimeCapabilities[i] = (byte)m_marshallingEngine.UnmarshalUB1();
				}
				num2 = m_marshallingEngine.UnmarshalUB1();
				if (num2 > 0)
				{
					m_serverRuntimeCapabilities = new byte[num2];
					for (int j = 0; j < num2; j++)
					{
						m_serverRuntimeCapabilities[j] = (byte)m_marshallingEngine.UnmarshalUB1();
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268566528, OracleTraceClassName.TTCProtocolNegotiation, OracleTraceFuncName.ReadResponse, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131584, OracleTraceClassName.TTCProtocolNegotiation, OracleTraceFuncName.ReadResponse);
				}
			}
		}
	}
}
